class xT_Weapons extends x_Weapons;

/*********************************************************************************************
 * Fire Fucntions
 *********************************************************************************************/
simulated function Projectile ProjectileFire()
{
	local Rotator      ProjectileStartrot;
	local vector       ProjectileStartLoc;
	local Projectile   SpawnedProjectile;
	local vector       offsetrotvector;
	local vector       ProjectileDirection;
	local xT_AIController PC;
	local xT_Pawn		P;
	local float		    AimPitchHigh;
	local vector		FireAtLocation; //PC.FireLocation value
	local vector		AimedFireLocation;
	local float         AimAccuracy;
	local int           NewDamage;

	AimPitchHigh=0;
	
	PC = xT_AIController(Instigator.Controller);
    P = xT_Pawn(Instigator);

    // tell remote clients that we fired, to trigger effects
    IncrementFlashCount();

    if( Role == ROLE_Authority )
    {
		ProjectileStartrot = P.rotation; //Projectile's rotation will be t/Projectile's pitch will be the same as the pawn's aimnode (from fspawn.facerotation)
		ProjectileStartLoc = Location;

		//Offset to where the muzzle would be  -temporary fix
		offsetrotvector = Vector(ProjectileStartrot);
		offsetrotvector.z = AimPitchHigh*0.00006;  //convert units
		ProjectileStartLoc.z += 1;
		ProjectileStartLoc +=offsetrotvector * 30;
		FireAtLocation = PC.EnemyAim.Location;
		FireAtLocation.z += P.GetEyeHeight()/3; //fire at center of enemy with eye height adjustment

		AimAccuracy = GetAccuracy();

		//AimedFireLocation = FireAtLocation + Vector((RotRand(true) * (1 - GetAccuracy()))*VRand()*;
		//AimedFireLocation = FireAtLocation + (Vsize(FireAtLocation-Location) * VRandCone(FireAtLocation-Location, 0.5) * (1 - GetAccuracy())); 
		AimedFireLocation = FireAtLocation + (Vsize(FireAtLocation-Location) * VRandCone(((FireAtLocation-Location)*(1-AimAccuracy)), (1-AimAccuracy) * PI/2) * (1 - AimAccuracy)); //best result but need to correct cone angle!
		//`log(" FireAtLocation : "$FireAtLocation);
		//`log(" AimedFireLocation : "$AimedFireLocation);

		ProjectileDirection =  AimedFireLocation - ProjectileStartLoc;
  		SpawnedProjectile = Spawn(GetProjectileClass(),self,,ProjectileStartLoc,ProjectileStartrot);

		NewDamage = int(RandRange(P.Data.Level, SpawnedProjectile.Damage));
		SpawnedProjectile.Damage = NewDamage;

  		if ((SpawnedProjectile != None) && (!SpawnedProjectile.bDeleteMe)) SpawnedProjectile.Init(normal(ProjectileDirection) );   //this is where you decide the projectile's direction of travel

  		return SpawnedProjectile;
     }
     return None;
}

function float GetAccuracy() 
{
	local float         lAccuracy;
	local xT_Pawn		P;
	local float         lPawnAccuracy;
	local float         lPositionAccuracyBonus;
	local float         lWeaponAccuracy;
	local float         lWoundsPenalty;

	/*
	% Chance to Hit = a * b * c * d * e * f, where 
	a = % Accuracy Stat of soldier 
	b = % Accuracy of weapon/shot 
	c = Kneeling bonus (115% if kneeling, 100% if standing) 
	d = One-handed penalty (80% if firing a two-handed weapon without a free hand, 100% otherwise) 
	e = Wounds penalty (% Health remaining) 
	f = Critical wounds penalty (100% - (10% for each critical wound to head or arms, up to 90%))
	*/
	P = xT_Pawn(Instigator);
	
	lPawnAccuracy = P.Data.Accuracy/100.0f;

	lWeaponAccuracy = AccuracyOfWeapon/100.0f;

	switch (P.Position)
	{
		case EP_Standing	:   lPositionAccuracyBonus = 1.00;
		break;
		case EP_Sitting	    :   if (WeaponType == EWT_Riffle) lPositionAccuracyBonus = 1.15;
									else lPositionAccuracyBonus = 0.80; //if grenade or stun-pod
		break;
		case EP_Howering	:   lPositionAccuracyBonus = 1.00;
		break;
	}	

	lWoundsPenalty = ((P.Health*100.)/P.HealthMax)/100.;

	lAccuracy = (lPawnAccuracy * lWeaponAccuracy * lPositionAccuracyBonus * lWoundsPenalty);

	if (lAccuracy >= 100.0) lAccuracy = 99.0; //should not be 100 or higher
	//`log(" lAccuracy : "$lAccuracy);
	//`log(" lPawnAccuracy : "$lPawnAccuracy$" lWeaponAccuracy : "$lWeaponAccuracy$" lPositionAccuracyBonus : "$lPositionAccuracyBonus$" lWoundsPenalty : "$lWoundsPenalty);
	return lAccuracy;
}

DefaultProperties
{
	//DroppedPickupMesh = Mesh
}